package com.xunfang.portal.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xunfang.common.RedisConst;
import com.xunfang.portal.model.entity.Address;
import com.xunfang.portal.model.entity.China;
import com.xunfang.portal.model.request.AddressRequest;
import com.xunfang.portal.model.vo.AddressVo;
import com.xunfang.portal.service.AddressService;
import com.xunfang.portal.mapper.AddressMapper;
import com.xunfang.portal.service.ChinaService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
* @author scott
* @description 针对表【t_address】的数据库操作Service实现
* @createDate 2025-10-20 10:14:32
*/
@Service
public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address>
    implements AddressService{

    @Autowired
    private AddressMapper addressMapper;

    @Override
    public List<AddressVo> findByUserId(Long userId) {

        //通过id查询address
        LambdaQueryWrapper<Address> wrapper = Wrappers.lambdaQuery(Address.class).eq(Address::getUserId, userId);
        List<Address> addressList = list(wrapper);
        //02 组装
        //将addressList转换成addressVoList
        List<AddressVo> list = addressList.stream().map(address -> {
            AddressVo addressVo = new AddressVo();
            addressVo.setId(address.getId());
            addressVo.setIsDefault(address.getIsDefault());  //默认地址
            //省+市+区+详细地址    广东省+东莞市+松山湖区+光大大硅谷WEC2栋305室
            String label = address.getProvince() + address.getCity() + address.getArea() + address.getDetailAddress();
            addressVo.setLabel(label);
            return addressVo;
        }).collect(Collectors.toList());

        return list;
    }

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ChinaService chinaService;

    /**
     * 查询所有的省份
     */
    @Override
    public List<China> getAllProvince() {
        List<China> list;
        // 判断缓存中是否有key
        if (!redisTemplate.hasKey(RedisConst.PROVINCES)) {
            // 查询数据库
            list = chinaService.list(
                    Wrappers.lambdaQuery(China.class)
                            .eq(China::getPid, 0)
                            .ne(China::getId, 0).orderByAsc(China::getId)
            );
            // 查询结果放入Redis缓存，通过zset集合存储，id是分数
            list.forEach(china -> redisTemplate.opsForZSet().add(RedisConst.PROVINCES, china, china.getId()));
        } else {
            // 从Redis中获取所有元素
            Set<China> members = redisTemplate.opsForZSet().range(RedisConst.PROVINCES, 0, -1);
            list = new ArrayList<>(members);
        }
        return list;
    }

    /**
     * 通过省的id查询省下所有的城市
     * #root.methodName 动态获取方法名称
     * #provinceId 动态获取方法参数
     */
    @Cacheable(cacheNames = RedisConst.CITIES, key = "#root.methodName + #provinceId")
    @Override
    public List<China> getAllCities(Integer provinceId) {
        List<China> list = chinaService.list(Wrappers.lambdaQuery(China.class)
                .eq(Objects.nonNull(provinceId), China::getPid, provinceId));
        return list;
    }

    /**
     * 通过城市的id查询城市下所有的地区
     *
     * @param cityId
     */
    @Override
    @Cacheable(cacheNames = RedisConst.DISTRICTS, key = "#root.methodName + #cityId")
    public List<China> getAllDistricts(Integer cityId) {
        List<China> list = chinaService.list(Wrappers.lambdaQuery(China.class)
                .eq(Objects.nonNull(cityId), China::getPid, cityId));
        return list;
    }

    @Override
    public void addAddress(AddressRequest addressRequest, Long userId) {

        // 根据省份id，获取省份名称
        China province = chinaService.findById(addressRequest.getProvince());
        // 获取城市id，获取城市名称
        China city = chinaService.findById(addressRequest.getCity());
        // 获取区/县id，获取区/县名称
        Integer district = addressRequest.getDistrict();
        // Optional.ofNullable(district) 创建一个 Optional 对象，然后调用 map(chinaService::findById) 方法来处理 district 不为空的情况，最后使用 orElse(null) 来处理 district 为空的情况，避免了显式的 if 判断语句，使代码更加简洁和优雅。
        China area = Optional.ofNullable(district)
                .map(chinaService::findById)
                .orElse(null);
        // 封装地址信息
        Address address = new Address();
        // 属性拷贝
        BeanUtils.copyProperties(addressRequest, address);
        // 属性不同的则单独设置
        address.setProvince(province.getName());
        address.setCity(city.getName());
        //如果为空，则赋值空字符串
        address.setArea(area == null ? "" : area.getName());
        address.setStatus("1");
        address.setTelephone(addressRequest.getTel());
        address.setUserId(userId);

        // 判断是否为默认地址
        if (address.getIsDefault() == 1) {
            // 修改其他地址为不是默认地址，将isDefault = 0
            this.update(Wrappers.lambdaUpdate(Address.class)
                    .set(Address::getIsDefault, "0").eq(Address::getUserId, userId));
        }
        // 添加地址
        addressMapper.insert(address);
    }
}




